const fs = require('fs');
const xlsx = require('node-xlsx');
const cheerio = require('cheerio');
const axios = require('axios');

const requestHeaders = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
  'Referer': 'http://money.163.com/',
};

class Crawler {
  constructor(options) {
    this.pageUrl = options.pageUrl;
    this.cachePath = options.cachePath || './cache.html';
    this.exportExcelPath = options.exportExcelPath || 'exportExcel.xlsx';
  }
  async start() {
    let html = await this.readLocalCache();
    if (!html) {
      html = await this.request();
    }
    this.processPageHTML(html);
    const parseResult = this.processPageHTML(html);
    this.buildXlsx(parseResult);
  }
  checkFileExist(filePath) {
    try {
      fs.statSync(filePath);
      return true;
    } catch (err) {
      fs.writeFileSync(filePath, '', 'utf-8');
      return false;
    }
  }
  createLocalCache(html = '') {
    this.checkFileExist(this.cachePath);
    return fs.writeFileSync(this.cachePath, html, 'utf-8');
  }
  async readLocalCache() {
    this.checkFileExist(this.cachePath);
    return fs.readFileSync(this.cachePath, 'utf-8');
  }
  async request() {
    return axios.get(this.pageUrl, {
      headers: requestHeaders
    }).then(result => {
      this.createLocalCache(result.data);
      return Promise.resolve(result.data);
    }).catch(err => {
      console.log('err');
      console.log(err);
      return Promise.reject(err);
    });
  }
  processPageHTML(html) {
    const result = { title: [], profitRateList: [] };
    const $ = cheerio.load(html);
    const $reportTable = $('.table_bg001.border_box.limit_sale.scr_table');
    const tableTitle = $reportTable.find('tbody tr:first-child');
    const tableTitleTds = tableTitle.children();
    const profitRateTr = $reportTable.find('tbody tr:nth-child(12)');
    const profitRateTds = profitRateTr.children();
    for (let i = 0; i < tableTitleTds.length; i++) {
      const titleTd = tableTitleTds[i];
      result.title.push($(titleTd).text().trim());
      const profitRateTd = profitRateTds[i];
      result.profitRateList.push($(profitRateTd).text().trim());
    }
    return result;
  }
  buildXlsx(dataObj) {
    const values = Object.values(dataObj);
    const excelBuffer = xlsx.build([{ name: 'maotai', data: values }]);
    fs.writeFileSync(this.exportExcelPath, excelBuffer, 'buffer');
    console.log('导出excel');
  }
}

const crawler = new Crawler({ pageUrl: 'http://quotes.money.163.com/f10/zycwzb_600519,report.html' });
crawler.start();